package cn.sycoder.controller;

import cn.sycoder.constant.Const;
import cn.sycoder.entity.BehaviorLog;
import cn.sycoder.entity.LoginRecords;
import cn.sycoder.entity.User;
import cn.sycoder.exception.BusinessException;
import cn.sycoder.exception.InterceptorException;
import cn.sycoder.exception.SystemException;
import cn.sycoder.mapper.BehaviorLogMapper;
import cn.sycoder.resp.Code;
import cn.sycoder.resp.Resp;
import cn.sycoder.resp.RespCode;
import cn.sycoder.service.IBehaviorLogService;
import cn.sycoder.service.ILoginRecordsService;
import cn.sycoder.service.IUserService;
import cn.sycoder.service.RedisService;
import cn.sycoder.utils.BaseDateUtils;
import cn.sycoder.utils.JwtUtil;
import cn.sycoder.utils.Md5Utils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;

import java.sql.Wrapper;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.sycoder.utils.BaseDateUtils.getLoginTableName;
import static cn.sycoder.utils.BaseDateUtils.getMonthByNowDate;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 杨润发
 * @since 2024-10-15
 */
@RestController
@RequestMapping("/api/login")
@Api(tags = "用户登录")
@Transactional(rollbackFor = Exception.class)
public class LoginController {

    @Autowired
    IUserService service;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    ILoginRecordsService loginRecordsService;

    @Autowired
    IBehaviorLogService behaviorLogService;

    @Autowired
    BehaviorLogMapper behaviorLogMapper;

    @Autowired
    RedisService redisService;


    @Value("${history.enable}")
    private Boolean behaviorEnabled;


    @PostMapping
    @ApiOperation(value = "用户名密码登录校验")
    public Map<String, Object> login(@RequestParam String username, @RequestParam String password) {

        // MD5 加密==
        String md5password = Md5Utils.hash(password);

        /**
         * 在用户登录的Controller中，主要处理用户提交的登录请求，验证用户名和密码的有效性，并在验证成功后生成JWT。
         * 这个JWT通常包含了用户的标识信息（如用户ID、用户名等），并通过密钥进行签名以确保其完整性和真实性。
         */
        try {
            // 模拟一个条件来抛出异常
//            boolean simulateError = true; // 您可以根据需要设置这个条件
//            if (simulateError) {
//                throw new InterceptorException(Code.INTERCEPTOR,"模拟的拦截器异常");
//            }
            Map<String, Object> response = new HashMap<>();
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.eq("user_name", username);

            User user = service.getOne(wrapper); // 查询用户名唯一的用户信息

            // 判断用户是否登录成功
            if (user != null && user.getUserPassword().equals(md5password)) { // 验证用户是否存在且用户登录密码是否正确

                // 生成JWT令牌，获取token信息
                String token = JwtUtil.createToken(user);

                // 将 token 和用户信息存入Redis（以 token = key，鉴权信息（info）= value）
                Map<String, Object> info = JwtUtil.authInfo(token); // 调用工具类获取鉴权信息（用户名，令牌时间）
                redisTemplate.opsForValue().set(token, info);

                // 登录成功响应
                response.put("success", true); // 登录成功
                response.put("token", token); // JWT令牌

                // redis => 获取鉴权信息
//                Map<String, Object> map = (Map<String, Object>) redisTemplate.opsForValue().get(token);
//                String v1 = (String) map.get("loginUserName"); // 登录用户名
//                Boolean v2 = (Boolean) map.get("isTokenExpired"); // 令牌是否过期 （false 未过期）
//
//                // 判断（获取登录鉴权信息，首先通过Redis进行判断）
//                if (username.equals(v1) && v2.equals(false)){ // redis 验证
//                    // 验证成功响应鉴权信息 token
//                    response.put("success", true); // 登录成功
//                    response.put("token", token); // JWT令牌
//                    System.out.println("========== redis ===========");
//
//                }else if(JwtUtil.verifyToken(token, username)) {  // jwt方法 => 获取登录鉴权信息（登录的用户名和令牌是否过期）
//                    // 验证成功响应鉴权信息 token
//                    response.put("success", true); // 登录成功
//                    response.put("token", token); // JWT令牌
//                    System.out.println("========== jwt方法 ==========");
//                } else {
//                    response.put("success", false);
//                    response.put("msg", "当前令牌已过期！");
//                }


                // 登录成功，将用户信息响应到前端
                Map<String, Object> userInfo = new HashMap<>();
                userInfo.put("username", user.getUserName());
                userInfo.put("role", user.getRoleId());
                response.put("data", userInfo); // 将用户名和角色响应到前端

                // 登录成功，执行用户登录行为数据记录（分表）
                if (behaviorEnabled) {
                    // 存储用户信息
                    behaviorLogMapper.insertBehavior(user.getUserId(), user.getUserName(), Const.LOGIN,
                            getLoginTableName(), new Date());
                }

            } else {
                response.put("success", false);
                response.put("msg", "用户名或密码错误");
            }
            return response;
        } catch (InterceptorException e) {
            throw new InterceptorException(Code.INTERCEPTOR, "系统繁忙，请稍后再试！");
        }

    }

    // 获取表明（通过月份）
    public static String getTableName() {
        return "behavior_log_" + getMonthByNowDate();
//        return "behavior_log_" + 12; // 模拟12月的登录用户
    }
}
